<!--
 * @Author: 吴世扬 18368095041@163.com
 * @Date: 2024-07-10 11:42:03
 * @LastEditors: 吴世扬 18368095041@163.com
 * @LastEditTime: 2024-08-19 16:16:11
 * @FilePath: /vue3-uniapp/src/components/ui/FixedTop/FixedTop.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script lang="ts" setup>
import { Subject } from 'rxjs';

import { useAfterAuth } from '@/service/hook/useAfterAuth';

import { useCurrentPageHeightSubject } from './useCurrentPageHeightChange';

const props = defineProps<{
    height?: number;
}>();
const emits = defineEmits<{
    (event: 'update:height', value: number): void;
}>();
const { height } = toRefs(props);

const statusBarHeight = uni.$uv.sys().statusBarHeight;

const phHeight = ref((statusBarHeight || 0) + 40);

watch(
    () => height.value,
    (newVal) => {
        if (typeof newVal === 'number') {
            phHeight.value = newVal;
        }
    }
);

const instance = getCurrentInstance();

const subject = new Subject<'mounted' | 'auth'>();
const source$ = subject.pipe(debounceTime(100));
const subscription = source$.subscribe({
    next: () => {
        resetHeight();
    }
});

const { notifyHeighChange } = useCurrentPageHeightSubject();

const resetHeight = async () => {
    const query = uni.createSelectorQuery().in(instance);
    query
        .select('.fixed-top-container')
        .boundingClientRect((data) => {
            const height = Array.isArray(data) ? data[0].height : data.height;
            if (height === undefined) {
                throw new Error('[FixedTop]获取不到内部组件高度');
            }
            phHeight.value = height;
            emits('update:height', height);
            notifyHeighChange(height);
        })
        .exec();
};

useAfterAuth(() => {
    subject.next('auth');
});
onMounted(() => {
    subject.next('mounted');
});
onBeforeUnmount(() => {
    subscription.unsubscribe();
});
</script>

<template>
    <view class="fixed-top-wrap">
        <view class="fixed-top-container" ref="containerRef">
            <slot></slot>
        </view>
        <view
            class="placeholder"
            :style="{
                height: phHeight + 'px'
            }"
        />
    </view>
</template>

<style lang="scss" scoped>
.fixed-top-container {
    width: 100%;
    position: fixed;
    left: 0;
    top: 0;
    z-index: 10;
}
</style>
